﻿using System;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using Common.Constants;
using Common.Helper;
using Entities;

namespace DataAccess
{
    public class ProgrammeDataAccess : IProgrammeDataAccess
    {
        /// <summary>
        /// Gets the instance.
        /// </summary>
        /// <value>
        /// The instance.
        /// </value>
        public static ProgrammeDataAccess Instance { get; private set; }
        /// <summary>
        /// Initializes the <see cref="ProgrammeDataAccess" /> class.
        /// </summary>
        static ProgrammeDataAccess() { Instance = new ProgrammeDataAccess(); }

        /// <summary>
        /// Extracts the raw data.
        /// </summary>
        /// <param name="dataReader">The data reader.</param>
        /// <returns></returns>
        private static Programme ExtractRawData(IDataRecord dataReader)
        {
            var programme = new Programme();

            programme.ProgrammeId = (Guid)dataReader["ProgrammeID"];
            programme.ContactId = (Guid)dataReader["ContactID"];
            programme.ProgrammeName = dataReader["ProgrammeName"].ToString();
            programme.Description = dataReader["Description"].ToString();
            bool active;
            if (bool.TryParse(dataReader["Active"].ToString(), out active))
                programme.Active = active;

            return programme;

        }

        /// <summary>
        /// Inserts the specified programme.
        /// </summary>
        /// <param name="programme">The programme.</param>
        /// <returns></returns>
        public int Insert(Programme programme)
        {
            var colParameter = new Collection<SqlParameter>
                  {
                        new SqlParameter("ProgrammeID", programme.ProgrammeId),
                        new SqlParameter("ContactID", programme.ContactId),
                        new SqlParameter("ProgrammeName", programme.ProgrammeName),
                        new SqlParameter("Description", programme.Description),
                        new SqlParameter("Active", programme.Active)
                    };
            var result = SqlHelper.ExecuteNonQuery(ProcedureStores.InsertProgramme, colParameter);
            return result;
        }

        /// <summary>
        /// Updates the specified programme.
        /// </summary>
        /// <param name="programme">The programme.</param>
        /// <returns></returns>
        public int Update(Programme programme)
        {
            if (programme == null) return -1;
            var colParameter = new Collection<SqlParameter>
                                   {
                                       new SqlParameter("ProgrammeId",programme.ProgrammeId),
                                       new SqlParameter("ContactId",programme.ContactId),
                                       new SqlParameter("ProgrammeName",programme.ProgrammeName),
                                       new SqlParameter("Description",programme.Description),
                                       new SqlParameter("Active",programme.Active)
                                   };
            var result = SqlHelper.ExecuteNonQuery(ProcedureStores.ProgrammeEdits, colParameter);
            return result;
        }



        /// <summary>
        /// Gets the programme by id.
        /// </summary>
        /// <param name="programmeId">The programme id.</param>
        /// <returns></returns>
        public Programme GetProgrammeById(string programmeId)
        {
            var colParameter = new Collection<SqlParameter> { new SqlParameter("ProgrammeID", programmeId) };

            using (var reader = SqlHelper.ExecuteReader(ProcedureStores.GetProgrammeById, colParameter))
            {
                if (reader.Read())
                {
                    var result = ExtractRawData(reader);

                    return result;
                }
                return null;
            }
        }

        /// <summary>
        /// Shows the list programme.
        /// </summary>
        /// <param name="active">if set to <c>true</c> [active].</param>
        /// <returns></returns>
        public Collection<Programme> ShowListProgramme(bool active)
        {
            var lstProgramme = new Collection<Programme>();

            var colParameter = new Collection<SqlParameter>
                                   {
                                       new SqlParameter("Include", active)
                                   };
            using (var reader = SqlHelper.ExecuteReader(ProcedureStores.ShowListProgramme, colParameter))
            {
                while (reader.Read())
                {
                    var result = ExtractRawData(reader);
                    lstProgramme.Add(result);
                }
                return lstProgramme;
            }
        }

        /// <summary>
        /// Filters the specified keyword.
        /// </summary>
        /// <param name="keyword">The keyword.</param>
        /// <param name="includeInactive">if set to <c>true</c> [include inactive].</param>
        /// <returns></returns>
        public Collection<Programme> Filter(string keyword, bool includeInactive)
        {
            var listResult = new Collection<Programme>();
            Collection<Programme> listProgramme = ShowListProgramme(includeInactive);

            const string digitPattern = "^[0-9]";
            const string aePattern = "^[a-eA-E]";
            const string fjPattern = "^[f-jF-J]";
            const string knPattern = "^[k-nK-N]";
            const string orPattern = "^[o-rO-R]";
            const string svPattern = "^[s-vS-V]";
            const string wzPattern = "^[w-zW-Z]";

            if (keyword.Equals("ae"))
            {
                foreach (var programme in listProgramme)
                {
                    if (checkPattern(aePattern, programme.ProgrammeName))
                    {
                        listResult.Add(programme);
                    }
                }
            }
            else if (keyword.Equals("fj"))
            {
                foreach (var programme in listProgramme)
                {
                    if (checkPattern(fjPattern, programme.ProgrammeName))
                    {
                        listResult.Add(programme);
                    }
                }
            }
            else if (keyword.Equals("kn"))
            {
                foreach (var programme in listProgramme)
                {
                    if (checkPattern(knPattern, programme.ProgrammeName))
                    {
                        listResult.Add(programme);
                    }
                }
            }
            else if (keyword.Equals("or"))
            {
                foreach (var programme in listProgramme)
                {
                    if (checkPattern(orPattern, programme.ProgrammeName))
                    {
                        listResult.Add(programme);
                    }
                }
            }
            else if (keyword.Equals("sv"))
            {
                foreach (var programme in listProgramme)
                {
                    if (checkPattern(svPattern, programme.ProgrammeName))
                    {
                        listResult.Add(programme);
                    }
                }
            }
            else if (keyword.Equals("wz"))
            {
                foreach (var programme in listProgramme)
                {
                    if (checkPattern(wzPattern, programme.ProgrammeName))
                    {
                        listResult.Add(programme);
                    }
                }
            }
            else if (keyword.Equals("09"))
            {
                foreach (var programme in listProgramme)
                {
                    if (checkPattern(digitPattern, programme.ProgrammeName))
                    {
                        listResult.Add(programme);
                    }
                }
            }
            else if (keyword.Equals("all"))
            {
                return listProgramme;
            }
            else
            {
                return null;
            }
            return listResult;
        }

        /// <summary>
        /// Checks the pattern.
        /// </summary>
        /// <param name="pattern">The pattern.</param>
        /// <param name="target">The target.</param>
        /// <returns></returns>
        private bool checkPattern(string pattern, string target)
        {
            var myRegex = new Regex(pattern);
            var match = myRegex.Match(target);
            return match.Success;
        }
        /// <summary>
        /// Checks the link to service.
        /// </summary>
        /// <param name="contactId">The contact id.</param>
        /// <returns></returns>
        public bool CheckLinkToService(string contactId)
        {
            var colParameter = new Collection<SqlParameter> { new SqlParameter("ContactId", contactId) };

            using (var reader = SqlHelper.ExecuteReader(ProcedureStores.CheckProgrammeLinkToService, colParameter))
            {
                if (reader.Read())
                {
                    return true;
                }
                return false;
            }
        }
    }
}
